/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "yaffut.h"
#include "myassert.h"

#include "Respawner.h"
#include "Error.h"
#include "MudObject.h"
#include "Global.h"
#include "TaskQueue.h"

using namespace std;
using namespace Chronos;

class TestRespawner : public Respawner {
public:
    TestRespawner(bool* d)
        : Respawner(1)
        , hasSpawn(false)
        , isDeleted(d)
    {}
    ~TestRespawner() {
        *isDeleted = true;
    }
    virtual void spawn() { hasSpawn = true; }

    bool hasSpawn;
    bool* isDeleted;
};


class RespawnTestObject : public MudObject {
public:
	RespawnTestObject(const string& name)
		: MudObject(name, "descr")
	{}
    void pickup() {
        generateEvent(MUDITEM_PICKUP);
    }
};


struct RespawnerTest {
    RespawnerTest()
        : isDeleted(false)
        , taskQueue(0)
        , respawner(new TestRespawner(&isDeleted))
        , object("", "")
    {
        Global<TaskQueue>::set(&taskQueue);
    }
    ~RespawnerTest() {
        if (!isDeleted) delete respawner;
    }
    bool isDeleted;
    TaskQueue taskQueue;
    TestRespawner* respawner;
    MudObject object;
};


TEST(RespawnerTest, respawnerShouldDeleteItself) {
    ASSERT_FALSE(respawner->handleObjectEvent(object, OBJECT_DESTRUCTION));
    ASSERT_TRUE(isDeleted);
}


TEST(RespawnerTest, respawnerShouldSpawnOnPickup) {
    ASSERT_FALSE(respawner->handleObjectEvent(object, MUDITEM_PICKUP));
    ASSERT_FALSE(isDeleted);
    taskQueue.runNextTime();
    ASSERT_TRUE(respawner->hasSpawn);
}


TEST(RespawnerTest, respawnerShouldSpawnOnDeath) {
    ASSERT_FALSE(respawner->handleObjectEvent(object, MUDMOBILE_DEATH));
    ASSERT_FALSE(isDeleted);
    taskQueue.runNextTime();
    ASSERT_TRUE(respawner->hasSpawn);
}


TEST(RespawnerTest, respawnerShouldNotSpawnOnOtherEvent) {
    /*
    ASSERT_TRUE(respawner->handleObjectEvent(object, TODO));
    ASSERT_FALSE(isDeleted);
    taskQueue.runNextTime();
    ASSERT_FALSE(respawner->hasSpawn);
    */
}

